package com.landmesure.communication;

import android.util.Log;

import com.code.CollectData;
import com.code.EntityType;
import com.code.PropertyDefinition;
import com.code.ValueType;
import com.landmesure.bluetoothchat.constant.Constant;
import com.landmesure.bluetoothchat.view.BluetoothFragment;

import com.landmesure.utils.PropertyBuilder;
import com.sensor.core.HandlerMessage;
import com.util.ByteUtil;

import org.apache.commons.lang3.RandomUtils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import static android.content.ContentValues.TAG;
import static com.landmesure.communication.ReadBoardManager.reset;
import static com.landmesure.communication.ReadBoardManager.setArgs;

public class SendMessageService {

    /*
     * 设置参数，选测，查询测量板,管理板
     * */

    public void sendMessage(EntityType entityType, int monitorType, ArrayList arrayList, String message) throws Exception {
        CommunicationPlatform.monitorType = monitorType;

        CommunicationPlatform.deadlineTime = System.currentTimeMillis() + CommunicationPlatform.OVER_TIME;
        CommunicationPlatform.sending = true;
        switch (monitorType) {
            case Constant.SETUP_PARAMETERS: {
                setArgs = true;//设置参数
                CollectData collectData = (CollectData) BluetoothFragment.collectDataMap.get(BluetoothFragment.classKey).get(0);//判断空对象
                for (PropertyDefinition propertyDefinition : entityType.getPropertyDefinitions()
                ) {
                    if (propertyDefinition.getCode() == Integer.parseInt(String.valueOf(arrayList.get(0)))) {
                        String sendMessage = combineMessageForSetupParameters(entityType, collectData, propertyDefinition);
                        SendMessageThread.addTask(sendMessage);
                    }
                }
                break;
            }
            case Constant.SELECT_TEST:
                setArgs = true;//设置参数
                CollectData collectData = (CollectData) BluetoothFragment.collectDataMap.get(BluetoothFragment.classKey).get(0);
                String sendMessage = combineMessageForSelectTest(entityType, collectData);
                Log.i(TAG, "yuan选测数据: " + sendMessage);
                Log.i(TAG, "yuan选测对象: " + entityType.getName());
                selectTest(entityType, sendMessage);
                break;
            case Constant.QUERY_MEASUREMENT_BOARD:
                setArgs = false;//设置参数
                sendMessage = combineMessageForMeasure(entityType, (CollectData) BluetoothFragment.collectDataMap.get("通讯管理板1").get(0));
                SendMessageThread.addTask(sendMessage);
                break;
            case Constant.RESET:
                setArgs = true;//设置参数
                reset = true;//是否复位
                sendMessage = combineMessageForReset(entityType, (CollectData) BluetoothFragment.collectDataMap.get(BluetoothFragment.classKey).get(0));
                SendMessageThread.addTask(sendMessage);
                break;
            case Constant.QUERY_PARAMETERS:
                setArgs = true;//设置参数
                sendMessage = combineMessageForQueryParameter(entityType, (CollectData) BluetoothFragment.collectDataMap.get(BluetoothFragment.classKey).get(0), Integer.parseInt((String) arrayList.get(0)));
                SendMessageThread.addTask(sendMessage);
                break;
            case Constant.QUERY_MANAGEMENT_BOARD: {
                sendMessage = combineMessageForManagement();
                SendMessageThread.addTask(sendMessage);
                break;

            }
            case HandlerMessage.ShengYaJi.READ_BZDL:
            case HandlerMessage.ShengYaJi.READ_SYJ:
            case HandlerMessage.WaterMonitor.WATER_MONITER:
                {
                SendMessageThread.addTask(message);
                break;
            }
            default:
                SendMessageThread.addTask(message);
                break;
        }


    }

    private String combineMessageForManagement() {
        String sendMessage;
        sendMessage = "EB9506FFFF0041000000000200FFFE0102000CCD1C22";
        try {
            sendMessage.getBytes("ISO_8859_1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return sendMessage;
    }

    private void selectTest(EntityType entityType, String sendMessage) {

        switch (entityType.getName()) {
            case "数字式顷角传感器": {
                CommunicationPlatform.SLEEP_TIME = 3000;
                ReadBoardManager.allTestMessages = new ArrayList<>();
                for (int k = 0; k < 20; k++) {
                    SendMessageThread.addTask(sendMessage);
                }
                break;
            }
            default:
                SendMessageThread.addTask(sendMessage);
        }


    }

    private String combineMessageForReset(EntityType entityType, CollectData collectData
    ) {

        StringBuilder sbcode = new StringBuilder();
        sbcode.append("06");//命令类型
        sbcode.append(collectData.getPcode());
        sbcode.append(String.format("%04X", entityType.getEcode()));
        sbcode.append("0102");//大小类编码
        StringBuilder scode = new StringBuilder();
        scode.append("EB95");
        scode.append(String.format("%02X", sbcode.length() / 2));
        scode.append(String.format("%04X", (collectData.getSourceStation() << 6) + collectData
                .getSourceGroup()));//板号改变
        scode.append(String.format("%04X", (collectData.getTargetStation() << 6) + collectData
                .getTargetGroup()));
        Log.d(TAG, "jnvshcnsnjnveensn: " + String.format("%04X", (collectData.getTargetStation() << 6) + collectData
                .getTargetGroup()));
        scode.append("0000");
        scode.append("0000");
        scode.append(sbcode);
        scode.append("00");
        scode.append(String.format("%04X", RandomUtils.nextInt(1, 65533)));//"0000"
        scode.append(String.format("%04X", ByteUtil.buildCrc16(scode.toString())));
        return scode.toString();
    }

    private String combineMessageForQueryParameter(EntityType entityType, CollectData collectData,
                                                   int code) {

        StringBuilder sbcode = new StringBuilder();
        sbcode.append("02");//命令类型
        sbcode.append(collectData.getPcode());
        sbcode.append(String.format("%04X", entityType.getEcode()));
        sbcode.append("0102");//大小类编码
        sbcode.append(String.format("%02X", code));
        StringBuilder scode = new StringBuilder();
        scode.append("EB95");
        scode.append(String.format("%02X", sbcode.length() / 2));
        scode.append(String.format("%04X", (collectData.getSourceStation() << 6) + collectData
                .getSourceGroup()));//板号改变
        scode.append(String.format("%04X", (collectData.getTargetStation() << 6) + collectData
                .getTargetGroup()));
        scode.append("0000");
        scode.append("0000");
        scode.append(sbcode);
        scode.append("00");
        scode.append(String.format("%04X", RandomUtils.nextInt(1, 65533)));//"0000"
        scode.append(String.format("%04X", ByteUtil.buildCrc16(scode.toString())));
        return scode.toString();
    }

    private String combineMessageForMeasure(EntityType entityType, CollectData collectData
    ) {

        StringBuilder sbcode = new StringBuilder();
        sbcode.append("02");//命令类型
        sbcode.append(collectData.getPcode());
        sbcode.append("FFFE");
        sbcode.append("0102");//大小类编码
        StringBuilder scode = new StringBuilder();
        scode.append("EB95");
        scode.append(String.format("%02X", sbcode.length() / 2));
        scode.append(String.format("%04X", (collectData.getSourceStation() << 6) + collectData
                .getSourceGroup() + entityType.getEcode() - 1));//板号改变
        scode.append(String.format("%04X", (collectData.getTargetStation() << 6) + collectData
                .getTargetGroup()));
        scode.append("0000");
        scode.append("0000");
        scode.append(sbcode);
        scode.append("00");
        scode.append(String.format("%04X", RandomUtils.nextInt(1, 65533)));//"0000"
        scode.append(String.format("%04X", ByteUtil.buildCrc16(scode.toString())));
        return scode.toString();
    }

    private String combineMessageForSelectTest(EntityType entityType, CollectData collectData
    ) {
        StringBuilder sbcode = new StringBuilder();
        sbcode.append("33");//命令类型
        sbcode.append(collectData.getPcode());
        sbcode.append(String.format("%04X", entityType.getEcode()));
        StringBuilder scode = new StringBuilder();
        scode.append("EB95");
        scode.append(String.format("%02X", sbcode.length() / 2));
        scode.append(String.format("%04X", (collectData.getSourceStation() << 6) + collectData
                .getSourceGroup()));
        scode.append(String.format("%04X", (collectData.getTargetStation() << 6) + collectData
                .getTargetGroup()));
        scode.append("0000");
        scode.append("0000");
        scode.append(sbcode);
        scode.append("00");
        scode.append(String.format("%04X", RandomUtils.nextInt(1, 65533)));//"0000"
        scode.append(String.format("%04X", ByteUtil.buildCrc16(scode.toString())));
        return scode.toString();
    }

    private String combineMessageForSetupParameters(EntityType entityType, CollectData collectData,
                                                    PropertyDefinition propertyDefinition) throws Exception {
        String code = String.format("%02X", entityType.getCode());
        String mcode = String.format("%02X", entityType.getMcode());
        String vtype = propertyDefinition.getVtype();//数据类型
        String value = switchValue(vtype, propertyDefinition);//参数值

        StringBuilder sbcode = new StringBuilder();
        sbcode.append("01");//命令类型
        sbcode.append(collectData.getPcode());
        sbcode.append(String.format("%04X", entityType.getEcode()));//从对象中取对象编号
        sbcode.append("01");
        sbcode.append(mcode);//大类编码
        sbcode.append("02");
        sbcode.append(code);//小类编码
        sbcode.append(String.format("%02X", propertyDefinition.getCode()));
        sbcode.append(value);
        StringBuilder scode = new StringBuilder();
        scode.append("EB95");
        scode.append(String.format("%02X", sbcode.length() / 2));
        scode.append(String.format("%04X", (collectData.getSourceStation() << 6) + collectData.getSourceGroup()));
        scode.append(String.format("%04X", (collectData.getTargetStation() << 6) + collectData.getTargetGroup()));
        scode.append("0000");
        scode.append("0000");
        scode.append(sbcode);
        scode.append("00");
        scode.append(String.format("%04X", RandomUtils.nextInt(1, 65533)));//"0000"
        scode.append(String.format("%04X", ByteUtil.buildCrc16(scode.toString())));
        return scode.toString();
    }

    private String switchValue(String vtype, PropertyDefinition propertyDefinition) throws Exception {
        String value;
        switch (vtype) {
            case ValueType.INTEGER:
                value = PropertyBuilder
                        .IntegerBuilder.encode(propertyDefinition.getValue(), propertyDefinition
                                .getDataLength());
                return value;
            case ValueType.DOUBLE:
                value = PropertyBuilder
                        .FloatBuilder.encode(propertyDefinition.getValue(), propertyDefinition
                                .getDataLength());
                return value;
            case ValueType.BOOLEAN:
                value = PropertyBuilder
                        .BooleanBuilder.encode(propertyDefinition.getValue(), propertyDefinition
                                .getDataLength());
                return value;
            case ValueType.STRING:
                value = PropertyBuilder
                        .AscBuilder.encode(propertyDefinition.getValue(), propertyDefinition
                                .getDataLength());
                return value;
            case ValueType.TIME:
                value = PropertyBuilder
                        .TimeBuilder.encode(propertyDefinition.getValue(), propertyDefinition
                                .getDataLength());
                return value;
            case ValueType.DATETIME:
                value = PropertyBuilder
                        .DatetimeBuilder.encode(propertyDefinition.getValue(), propertyDefinition
                                .getDataLength());
                return value;
            default:
                value = propertyDefinition.getValue();
                return value;
        }
    }
}
